package weeny.pre.face;

import java.io.InputStream;
import java.io.OutputStream;

import prefuse.data.Graph;
import prefuse.data.Table;
import prefuse.data.Tuple;
import prefuse.data.column.Column;
import weeny.face.LoadSaveBox;
import weeny.pre.io.MyGraphReader;
import weeny.pre.io.MyGraphWriter;
import weeny.util.logs.Debug;

/**
 * create the load & save control of the view, 
 * such as the positions, size, shaps... attributes.
 * Every field in graph will be saved.
 */

public class GraphLoadSaveBox extends LoadSaveBox{
	private Graph graph = null;
	private void validateFields(Table newTable, Table oldTable){
		//if the newTable has some columns the old one does not, add them
		//if the the new type can not be assigned to the old one, replace it
		for(int i = 0; i<newTable.getColumnCount(); i++){
			String field = newTable.getColumnName(i);
			Class   type = newTable.getColumnType(i);
			Object   dft = newTable.getDefault(field);
			Column   col = oldTable.getColumn(field);
			if (col == null) {
				oldTable.addColumn(field, type, dft);
			}
			else if (!col.getColumnType().isAssignableFrom(type)){
				Debug.prob("type conflict in field ("+ field+") " +
						": removing "+col.getColumnType()+", adding "+type);
				oldTable.removeColumn(field);
				oldTable.addColumn(field, type, dft);
			}
		}
	}
	public void loadData(InputStream is){
		graph.clear();
		Graph input = new MyGraphReader().safeRead(is);
		validateFields(input.getNodeTable(), graph.getNodeTable());
		validateFields(input.getEdgeTable(), graph.getEdgeTable());
		for(int i = 0; i<input.getNodeCount(); i++){
			Tuple node = graph.getNodeTable().addTuple(input.getNode(i));
			if (node == null) {
				throw new IllegalStateException("Fail to add node");
			}
		}
		for(int i = 0; i<input.getEdgeCount(); i++){
			Tuple edge = graph.getEdgeTable().addTuple(input.getEdge(i));
			if (edge == null) {
				throw new IllegalStateException("Fail to add edge");
			}
		}
	}
	public void saveData(OutputStream os){
		new MyGraphWriter().safeWrite(graph, os);
	}
	public GraphLoadSaveBox(String file, Graph graph, String title){
		super(file, title);
		this.graph = graph;
	}
}